package kt;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import ie.omk.smpp.Connection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Date;

import kt.dal.DAL;
import kt.dal.DBPoolX;
import kt.smpp.observer.AsyncObserver;
import kt.util.CommonUtil;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

public class SMSGWThread extends Thread{

	static Logger logger = LogManager.getLogger(SMSGWThread.class);
	
	static Connection smscCnn;
	static BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
	private static boolean running;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			loadConfigAndSeqNo();
			
			makeConnectionToSMSC();
			
			logger.info("start the SendMT schedulers..., secondly forever");
			startSendMTScheduler(); 	
			
			logger.info("start the Ping2SMSC scheduler..., every 30s");
			startPing2SMSCScheduler();
			
			//logger.info("start Send1765Winners scheduler..., every Thur 0:00");
			//startSend1765Winners();
			
			//logger.info("start DailyReport scheduler..., daily at 8:45");
			//startDailyReport();
			
			//logger.info("start the SendTempMT schedulers..., minutely forever");
			//startSendTempMTScheduler(); 
			
			new SMSGWThread().start();
			
		} catch (Exception e) {
			System.out.println("Error when make connection. ");
			System.exit(1);
		}
	}

	private static void loadConfigAndSeqNo() throws IOException {
		logger.info("Loading SMSC config info............");
		GWConfig.parameters = CommonUtil.loadSMSCDataFromConfig();
		int startSEQ_NO = DAL.getStartSEQ_NO(GWConfig.parameters.operator);
		GWConfig.parameters.startSeqNo = startSEQ_NO;
		logger.info("SMSC parameter loaded " + GWConfig.parameters);
	}

	private static void makeConnectionToSMSC() throws UnknownHostException,
			IOException {
		logger.info("Making connection...........");
		smscCnn = new Connection(GWConfig.parameters.hostName, GWConfig.parameters.port, true);
		AsyncObserver asyncObserver = new AsyncObserver();
		smscCnn.addObserver(asyncObserver);		
		
		logger.info("Binding to the SMSC...");
		smscCnn.bind(Connection.TRANSCEIVER, GWConfig.parameters.systemID,
				GWConfig.parameters.password, GWConfig.parameters.systemType,
				GWConfig.parameters.sourceTON, GWConfig.parameters.sourceNPI,
				GWConfig.parameters.sourceAddress);
		logger.info("Default alphabet" + smscCnn.getDefaultAlphabet());
	}
	
	private static void startSendMTScheduler() throws SchedulerException {
		Scheduler schedulerMT = new StdSchedulerFactory().getScheduler();
		Trigger triggerSendMT =  newTrigger().startNow()
				.withIdentity("triggerSendMT", "SendMT") 
				.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever()) 
				.build();
		JobDetail jdSendCDRCompare = newJob(SendMTJob.class)
			.withIdentity("SendMTJob", "SendMT").build();

		schedulerMT.scheduleJob(jdSendCDRCompare, triggerSendMT);
		
		schedulerMT.start();
	}

	private static void startSendTempMTScheduler() throws SchedulerException {
		Scheduler schedulerMT = new StdSchedulerFactory().getScheduler();
		Trigger triggerSendMT =  newTrigger().startNow()
				.withIdentity("triggerSendTempMT", "SendMT") 
				.withSchedule(SimpleScheduleBuilder.repeatMinutelyForever()) 
				.build();
		JobDetail jdSendCDRCompare = newJob(SendTempMTJob.class)
			.withIdentity("SendTempMTJob", "SendMT").build();

		schedulerMT.scheduleJob(jdSendCDRCompare, triggerSendMT);
		
		schedulerMT.start();
	}

	
	private static void startPing2SMSCScheduler() throws SchedulerException {
		Scheduler schedulerPing2SMSC = new StdSchedulerFactory().getScheduler();
		Trigger triggerSendCDRCompare =  newTrigger().startAt(new Date(System.currentTimeMillis() + 30000))
				.withIdentity("triggerPing2SMSC", "Ping2SMSC") 
				.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(30)) 
				.build();
		JobDetail jdSendCDRCompare = newJob(Ping2SMSCJob.class)
			.withIdentity("Ping2SMSCJob", "Ping2SMSC").build();
		
		//jdCheckRegister.getJobDataMap().put("RegisterCharger", chargerGW);
		schedulerPing2SMSC.scheduleJob(jdSendCDRCompare, triggerSendCDRCompare);
		
		schedulerPing2SMSC.start();
	}
	
	private static void startSend1765Winners() throws SchedulerException {
		Scheduler schedulerMT = new StdSchedulerFactory().getScheduler();
		Trigger triggerSendMT =  newTrigger().startNow()
				.withIdentity("triggerSend1765Winners", "1765") 
				.withSchedule(CronScheduleBuilder.weeklyOnDayAndHourAndMinute(Calendar.WEDNESDAY, 23, 59)) 
				.build();
		JobDetail jdSendCDRCompare = newJob(SelectWinner1765Job.class)
			.withIdentity("Send1765WinnersJob", "1765").build();

		schedulerMT.scheduleJob(jdSendCDRCompare, triggerSendMT);
		
		schedulerMT.start();
	}
	
	
	private static void startDailyReport() throws SchedulerException {
		Scheduler schedulerMT = new StdSchedulerFactory().getScheduler();
		Trigger triggerSendMT =  newTrigger().startNow()
				.withIdentity("triggerDailyReport", "6155") 
				.withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(23, 23)) 
				.build();
		JobDetail jdSendCDRCompare = newJob(DailyReportJob.class)
			.withIdentity("DailyReportJob", "6155").build();

		schedulerMT.scheduleJob(jdSendCDRCompare, triggerSendMT);
		
		schedulerMT.start();
	}

	
	
	public void run() {
		while (true)
			showMenu();
	}
	
	public static boolean isRunning() {
		return running;
	}

	private void showMenu() {
		System.out.println();
		System.out.println("Q - Quit");
		System.out.println("T-Test MO");
		System.out.println("S-Test Send MT");
		String option = "";
		try {
			option = keyboard.readLine();
		} catch (Exception localException) {
		}
		option = option.toUpperCase();
		if ("Q".equals(option)) {
			logger.info("Receive key Q to quit the app");
			try {
				if(smscCnn.isBound()){
					logger.info("Unbinding the connection");
					smscCnn.unbind();
					Thread.sleep(1000);
				}
				logger.info("Closing the connection");
				smscCnn.closeLink();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			DBPoolX.releaseAll();
			running = false;
			logger.info("CLOSED");
			System.exit(1);
		} 
	}
}
